package GUI;

import Controllers.*;
import elevatorsimulator.WorldBuilder;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

/**
 * Michael Peever
 * Controls Elevator Display
 */
public class ElevatorUI extends JPanel {

    WorldBuilder wb;
    FloorUI fd;
    String ELEVATORDISPLAYBORDERTITLE = "Elevator Console";
    JPanel floorBttnPanel = new JPanel(new GridLayout(7, 3));
    String ELEVATORFLOORBTTNDISPLAYBORDERTITLE = "Elevator View";
    String ELEVATORFLOORNUMDISPLAYBORDERTITLE = "Current Floor";
    String ELEVATORDIRECTIONSTATUSBORDERTITLE = "Direction";
    String UPARROW = "↑";
    String DOWNARROW = "↓";
    String INTRANSIT = "^_^";
    String NULL = "";
    String DOOROPEN = "[|   |]";
    String DOORCLOSED = "[|]";

    int soundCounter = 0;

    //Parent Panels
    JPanel elevatorViewPanel = new JPanel();
    JPanel elevatorStatusPanel = new JPanel();

    //Flags
    public boolean doorFlag = false;


    //arrays
    Object floorElevatorStatusPanel[];
    ArrayList<JLabel> elevatorDirectionLblArray = new ArrayList<JLabel>();
    ArrayList<JLabel> elevatorDoorStatusLblArray = new ArrayList<JLabel>();

    JLabel elevatorDirectionStatusLbl;
    JLabel floorNumLbl;

    /**
     * Creates the Elevator Display
     *
     * @param wb Takes in World Builder
     */
    public ElevatorUI(WorldBuilder wb) {

        this.wb = wb;
        setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), ELEVATORDISPLAYBORDERTITLE));

    }

    /**
     * Controls the clearing and adding of all Panels to master panel
     */
    public void viewCreator() {


        clearAllPanels();
        elevatorDirectionLblArray.clear();
        elevatorDoorStatusLblArray.clear();
        setLayout(new BorderLayout());
        elevatorFloorBttnGen();
        elevatorStatusPanelGen();
    }

    /**
     * Refreshes the elevator Status panel
     */
    public void viewRefresh() {

        elevatorLblRefresh();
    }

    /**
     * Controls the refreshing/updating of Label information for the Elevator
     */
    public void elevatorLblRefresh() {

        if (wb.b.getBuildingZone() == 'u') {
            if (wb.e.getCurrentFloor() == 0 || wb.e.getCurrentFloor() == 1) {
                floorNumLbl.setText("G");
            } else {
                System.out.println(wb.e.getCurrentFloor());
                floorNumLbl.setText(String.valueOf(wb.e.getCurrentFloor() - 1));
            }
        } else {
            if (wb.e.getCurrentFloor() == 0) {
                floorNumLbl.setText("1");
            } else {
                floorNumLbl.setText(String.valueOf(wb.e.getCurrentFloor()));
            }
        }

        floorNumLbl.updateUI();


        for (int k = 0; k < elevatorDoorStatusLblArray.size(); k++) {
            elevatorDoorStatusLblArray.get(k).setText(DOORCLOSED);


            if (wb.e.getDesiredFloor() == wb.e.getCurrentFloor() && doorFlag == false) {
                soundCounter++;
                if (wb.e.getDesiredFloor() > 0) {

                    elevatorDoorStatusLblArray.get(wb.e.getDesiredFloor() - 1).setText(DOOROPEN);
                    if (soundCounter == 1) {
                        new ArrivalSound().run();
                    }
                }

            }

        }
        for (int l = 0; l < elevatorDirectionLblArray.size(); l++) {

            if (l != wb.e.getDesiredFloor() - 1) {
                elevatorDirectionLblArray.get(l).setText(NULL);
                wb.e.setDirection(NULL);
                elevatorDirectionStatusLbl.setText(wb.e.getDirection());
                elevatorDirectionStatusLbl.updateUI();
            }
            elevatorDirectionLblArray.get(l).updateUI();
        }


        if (wb.e.getDesiredFloor() > wb.e.getCurrentFloor())

        {
            wb.e.setDirection(UPARROW);
            elevatorDirectionStatusLbl.setText(wb.e.getDirection());
            elevatorDirectionStatusLbl.updateUI();


            for (int k = 0; k < elevatorDirectionLblArray.size(); k++) {
                elevatorDirectionLblArray.get(k).setText(UPARROW);

            }

            wb.e.moveUp(wb.e.getCurrentFloor());
        }

        if (wb.e.getDesiredFloor() < wb.e.getCurrentFloor())

        {
            wb.e.setDirection(DOWNARROW);
            elevatorDirectionStatusLbl.setText(wb.e.getDirection());
            elevatorDirectionStatusLbl.updateUI();
            for (int j = 0; j < elevatorDirectionLblArray.size(); j++) {
                elevatorDirectionLblArray.get(j).setText(DOWNARROW);

            }

            wb.e.moveDown(wb.e.getCurrentFloor());
        }

        for (
                int i = 0;
                i < elevatorDirectionLblArray.size(); i++)

        {
            System.out.println(wb.e.getDesiredFloor());
            System.out.println(wb.e.getCurrentFloor());


            if (wb.e.getCurrentFloor() == i + 1) {
                elevatorDirectionLblArray.get(i).setText(INTRANSIT);
                if (wb.e.getDesiredFloor() > wb.e.getCurrentFloor()) {
                    if (i > 0) {
                        elevatorDirectionLblArray.get(i - 1).setText(UPARROW);

                    }
                }
                if (wb.e.getDesiredFloor() < wb.e.getCurrentFloor()) {
                    if (i < elevatorDirectionLblArray.size()) {
                        elevatorDirectionLblArray.get(i + 1).setText(DOWNARROW);
                    }
                }
                elevatorDirectionLblArray.get(i).updateUI();
            }
        }

        floorNumLbl.updateUI();

    }

    /**
     * Clears all Elevator Panels
     */
    public void clearAllPanels() {
        floorBttnPanel.removeAll();
        floorBttnPanel.repaint();
        floorBttnPanel.revalidate();

        elevatorStatusPanel.removeAll();
        elevatorStatusPanel.repaint();
        elevatorStatusPanel.revalidate();

    }

    /**
     * Generates elevator floor selection buttons
     */
    public void elevatorFloorBttnGen() {
        if (wb.b.getBuildingZone() == 'u') {
            System.out.println("UK/AUS");
            JButton gFloorNumBttn = new JButton("G");
            gFloorNumBttn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    new ElevatorFloorSelection().run(wb, 1);
                    doorFlag = false;
                    soundCounter = 0;
                }
            });
            floorBttnPanel.add(gFloorNumBttn);

            for (int dynamicFloorNum = 2; (dynamicFloorNum < (wb.b.getNumFloors() + 1)); dynamicFloorNum++) {
                JButton floorNumBttn = new JButton(String.valueOf(dynamicFloorNum - 1));
                final int finalDynamicFloorNum = dynamicFloorNum;
                floorNumBttn.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        new ElevatorFloorSelection().run(wb, finalDynamicFloorNum);
                        doorFlag = false;
                        soundCounter = 0;
                    }
                });
                floorBttnPanel.add(floorNumBttn);

            }
        }
        if (wb.b.getBuildingZone() == 'a') {
            System.out.println("USA");
            for (int dynamicFloorNum = 1; (dynamicFloorNum < wb.b.getNumFloors() + 1); dynamicFloorNum++) {
                JButton floorNumBttn = new JButton(String.valueOf(dynamicFloorNum));
                final int finalDynamicFloorNum = dynamicFloorNum;
                floorNumBttn.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        new ElevatorFloorSelection().run(wb, finalDynamicFloorNum);  //to be checked
                        doorFlag = false;
                        soundCounter = 0;
                    }
                });
                floorBttnPanel.add(floorNumBttn);
            }
        }

        add(elevatorViewPanel, BorderLayout.NORTH);
        elevatorViewPanel.add(floorBttnPanel, BorderLayout.WEST);
        elevatorViewPanel.add(elevatorStatusPanel, BorderLayout.CENTER);
        //Border

        floorBttnPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder()));
        elevatorViewPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), ELEVATORFLOORBTTNDISPLAYBORDERTITLE));
    }

    /**
     * Generates the elevator status panel
     */
    public void elevatorStatusPanelGen() {
        showElevatorFloorStatus();
        showElevatorDirectionStatus();
        showEmergencyStopFunction();
        showDoorControl();
        elevatorStatusPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder()));


    }

    /**
     * Displays the emergency stop button
     */
    public void showEmergencyStopFunction() {
        JPanel emegStopPanel = new JPanel();
        emegStopPanel.setPreferredSize(new Dimension(120, 70));
        String EMEGSTOP = "STOP";
        String EMEGSTOPBORDER = "Emergency Stop";
        JButton emegStopBttn = new JButton(EMEGSTOP);
        emegStopBttn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new EmegStop().run();
            }
        });
        emegStopPanel.add(emegStopBttn);
        emegStopPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), EMEGSTOPBORDER));
        elevatorStatusPanel.add(emegStopPanel);
    }

    /**
     * Displays the elevator direction status
     */
    public void showElevatorDirectionStatus() {
        JPanel elevatorDirectionStatusPanel = new JPanel();
        elevatorDirectionStatusPanel.setPreferredSize(new Dimension(120, 70));

        elevatorDirectionStatusLbl = new JLabel(wb.e.getDirection());
        elevatorDirectionStatusPanel.add(elevatorDirectionStatusLbl);
        elevatorDirectionStatusPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), ELEVATORDIRECTIONSTATUSBORDERTITLE));
        elevatorStatusPanel.add(elevatorDirectionStatusPanel);
    }

    /**
     * Displays elevator floor status
     */
    public void showElevatorFloorStatus() {
        //Current Floor
        JPanel elevatorFloorStatusPanel = new JPanel();
        elevatorFloorStatusPanel.setPreferredSize(new Dimension(120, 70));

        if (wb.b.getBuildingZone() == 'u') {
            floorNumLbl = new JLabel();
        } else {
            floorNumLbl = new JLabel(String.valueOf(wb.e.getCurrentFloor()));
        }
        elevatorFloorStatusPanel.add(floorNumLbl);
        elevatorFloorStatusPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), ELEVATORFLOORNUMDISPLAYBORDERTITLE));
        elevatorStatusPanel.add(elevatorFloorStatusPanel);
    }

    /**
     * Displays the door control(open/close) buttons
     */
    public void showDoorControl() {
        JPanel doorControl = new JPanel();
        JButton openBttn = new JButton("Open");
        openBttn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                doorFlag = false;
                new OpenElevatorDoor().run(wb, elevatorDoorStatusLblArray, DOOROPEN);
            }
        });
        JButton closeBttn = new JButton("Close");
        closeBttn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                doorFlag = true;
                new CloseElevatorDoor().run(wb, elevatorDoorStatusLblArray, DOORCLOSED);

            }
        });
        doorControl.add(openBttn, BorderLayout.NORTH);
        doorControl.add(closeBttn, BorderLayout.SOUTH);

        elevatorStatusPanel.add(doorControl);
    }


}


